package cn.itcast.aspect;

import cn.itcast.mapper.LogMapper;
import cn.itcast.pojo.Common;
import cn.itcast.pojo.OperateLog;
import com.alibaba.fastjson.JSONArray;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Map;


@Component
@Aspect
public class LogAspect {
    @Autowired
    private LogMapper logMapper;

    @Autowired
    private Common common;

    //绑定cn.itcast.service.下的删除,修改,添加方法
    @Around("execution(* cn.itcast.service.*.delete*(..)) || execution(* cn.itcast.service.*.update*(..)) || execution(* cn.itcast.service.*.add*(..))")
    public Object Log(ProceedingJoinPoint pjp) throws Throwable {
        // 消耗时间
        long start = 0;
        long end = 0;
        Object result = null;
        long constTime = 0;
        try {
            start = System.currentTimeMillis();
            result = pjp.proceed();
            end = System.currentTimeMillis();
            constTime = end - start;
            return result;
        } finally {
            //无论否发生异常，都会执行
            //获取方法参数
            Signature signature = pjp.getSignature();
            String methodnames = signature.getName();
            //获取类
            Class<?> aClass = pjp.getClass();
            //获取类的完整名称包括包名
            String classname = aClass.getName();

            OperateLog operateLog = new OperateLog();
            //获取参数
            Object[] args = pjp.getArgs();
            // 将方法参数数组转换为JSON格式字符串
            // 该代码将传入的参数数组args序列化为JSON字符串格式，便于后续处理或传输
            String methodParmas = JSONArray.toJSONString(args);

            //封装方法参数
            operateLog.setMethodParams(methodParmas);
            //获取时间
            operateLog.setOperateTime(LocalDateTime.now());
            //获取方法名
            operateLog.setMethodName(methodnames);
            //获取类名
            operateLog.setClassName(classname);
            //获取返回值
            operateLog.setReturnValue(result.toString());
            // 从线程本地变量中获取当前员工信息
            Map<String, Object> currentEmp = common.threadLocal.get();
            if (currentEmp != null) {

                // 设置操作日志的员工ID和操作时间
                operateLog.setOperateEmpId((Integer) currentEmp.get("id"));

                operateLog.setOperateTime(LocalDateTime.now());
                // 设置操作日志的员工名称
                operateLog.setOperateEmpName((String) currentEmp.get("name"));
                //获取耗时
                operateLog.setCostTime((int) constTime);
                logMapper.insertLog(operateLog);
            }
        }
    }
}


